#!usr/bin/env python3
# coding=utf-8
"""
本文件中代码实现了一个简单的服务器，配合同目录下的draw.html使用。服务器框架使用flask.

draw.html是一个h5 + js的前端，使用了h5的canvas和一些事件技术，让用户在网页上写字，然后将字迹图片和轨迹信息上传回来，
由本服务器接收并保存同目录下。网页传来的图片是png格式的base64数据，轨迹坐标是一个json列表。服务器将图片命名为
sample.png，轨迹坐标保存在文本文件中，名为sample.txt。网页每次上传数据，本服务器接收到后保存为文件，都会覆盖上一次
保存的文件。

当网页发起请求后，本服务器首先如上所述保存为文件，然后调用main2.py中的相关代码进行读取文件，进行识别，接着将识别结果以json
格式作为响应发送回网页。之所以要保存为文件，然后再读取这么绕一圈，来自于早期开发的代码遗留下来的历史原因（是的，这个开发
了一个星期项目已经背上历史的包袱了）。虽然仍然可以单独运行main2.py，但是已经没有任何的需要这么做了。

数据交互格式：
    请求: 网页 -> 服务器  POST
        发送用户输入（图片和字迹）：
        {
        'data': base64 编码后的png图片,
        'trajectory': 字迹采样点的坐标序列
        }

    响应: 服务器 -> 网页
        返回识别结果：
        {
        'success': "true" or "false",
        'digit': <int> or "FAIL",
        'image-raw-url': 获取字迹原图的url,
        'image-tra-url': 获取重采样点的可视化连线图的url
        }

2019-2-20
"""

import os
import base64
import json
import main2
import visualize_trajectory as visual_tra
from flask import request, send_file
from flask import Flask
app = Flask(__name__)


PORT = 8000  # the port that the server uses
SAMPLE_FILE_NAME = 'sample'  # the file name of the file that save the png picture of trajectory text
RESAMPLE_FILE_NAME = 'resample'  # used to save the visualized resampled points png

# if you want to print the result in the console, set it True. Or you want to speed up using IDLE,
# set it False to disable it
if_print = False


def get_page(filename='index2.html'):
    with open(filename, encoding='utf-8') as f:
        return ''.join(f.readlines())


def get_ip():
    import socket
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
    finally:
        s.close()

    return ip


@app.route(r'/', methods=['GET', 'POST'])
def interface():  # in fact, I don't know what to name it.
    if request.method == 'GET':
        return get_page()

    elif request.method == 'POST':
        img = request.form['image']
        img = img.split(',')[-1]
        img = base64.b64decode(img)
        tra = request.form['trajectory'].strip(',')
        tra = tra.replace(',,', ',')
        resp = {}
        with open('%s.png' % SAMPLE_FILE_NAME, 'wb') as f:
            f.write(img)
            f.close()

        with open('%s.txt' % SAMPLE_FILE_NAME, 'w') as f:
            f.write(tra)
            f.close()

        try:
            resp['digit'] = int(main2.recog_digit())
            resp['success'] = 'true'
            if if_print:
                print(main2.print_digit(int(resp['digit'])))
        except ValueError:
            resp['digit'] = 'FAIL'
            resp['success'] = 'false'

        resp['image-raw-url'] = '%s.png' % SAMPLE_FILE_NAME
        resp['image-tra-url'] = '%s.png' % RESAMPLE_FILE_NAME
        print("recognition result: ", resp)

        return json.dumps(resp)


@app.route(r'/favicon.ico')
def favicon():
    with open(os.path.join('static', 'favicon.ico'), 'rb') as f:
        return f.read()


@app.route(r'/%s.png' % SAMPLE_FILE_NAME, methods=['GET'])
def serve_sample():
    print("send sample")
    return send_file(r'D:\AAA_PersonalProjects\BBB_hwRecognition\hwRecognition\sample.png')


@app.route(r'/%s.png' % RESAMPLE_FILE_NAME)
def serve_resample():
    print("send resampled")
    points = visual_tra.get_points('%s.txt' % SAMPLE_FILE_NAME)
    img = visual_tra.draw_tra(points)

    f_name = '%s.png' % RESAMPLE_FILE_NAME
    img.save(f_name)
    return send_file(f_name)


if __name__ == "__main__":
    ip = get_ip()
    if ip is not None:
        print(u'要输入手写数字，请与本机在同一局域网内，并在浏览器输入该地址：http://{ip}:{port}'.format(ip=ip, port=PORT))
    else:
        print(u'获取地址出错，请自行在网络设置中查看本机IP。目前使用的端口为： %i' % PORT)

    app.run(host='0.0.0.0', port=PORT)
